package main

import (
	"fmt"
	"math/rand"
	"sort"
)

func main() {
	//1、看下面一段程序，回答问题
	//s1 := make([]int, 3, 4)
	//s2 := append(s1, 1)

	//请问s1、s2内各有什么元素？
	//答：s1 [0 0 0] s2[0 0 0 1]

	//s1修改一个元素会影响s2吗？s2修改一个元素会影响s1吗？
	//答：s1会影响s2，因为s1是长度为3容量为4的切片，s2在s1的基础上只添加了一个元素，没有超过容量，所以它们还是共用同一个底层数组
	//    s2修改前三个元素会影响s1，修改最后一个元素不会。虽然共用底层数组，但s1的长度是3，只显示3个元素，第四个元素的修改与它无关

	//s2再增加一个元素会怎么样？
	//答：s2会发生扩容，s1和s2的底层数组会发生分离，不在共用同一个。此时s2的长度为5，容量为8

	//2、有一个数组 [1,4,9,16,2,5,10,15]，生成一个新切片，要求新切片元素是数组相邻2项的和。
	s1 := [...]int{1, 4, 9, 16, 2, 5, 10, 15}
	s2 := []int{}
	for i, v := range s1 {
		if i == len(s1)-1 {
			break
		}
		s2 = append(s2, v+s1[i+1])
	}
	fmt.Println(s2) // [5 13 25 18 7 15 25]

	//3、数字重复统计
	//随机产生100个整数
	//数字的范围[-100, 100]
	//降序输出这些生成的数字并打印其重复的次数
	n := make([]int, 0, 100)
	for i := 0; i < 100; i++ {
		n = append(n, rand.Intn(201)-100)
	}
	sort.Sort(sort.Reverse(sort.IntSlice(n)))
	fmt.Println(n)
	m := make(map[int]int)
	for _, v := range n {
		m[v]++
	}
	ks := make([]int, 0, 100)
	for k, _ := range m {
		ks = append(ks, k)
	}
	sort.Sort(sort.Reverse(sort.IntSlice(ks)))
	for _, v := range ks {
		fmt.Println(v, m[v])
	}

	//4、简述线性数据结构和哈希表优劣
	//答：线性表具有两种存储结构，即顺序存储和链式存储。
	// 顺序存储优点：在尾部添加移除元素方便，通过索引定位效率高
	// 顺序存储缺点：在头部或中间添加移除元素效率慢，会使其他元素后移，时间复杂度O(n)
	// 链式存储优点：增删元素效率高，没有数据挪动
	// 链式存储缺点：查找时需要遍历，取每一个节点中保存的下一个地址，使用该地址定位下一个元素，时间复杂度O(n)

	// 哈希表优点：增删改查等操作效率高，时间复杂度接近O(1)
	// 哈希表缺点：存储数据过多，会产生冲突，当表中的数据超过负载因子，需要扩容，这是一个效率低下且耗时的操作。表中的数据没有顺序
}
